home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / correlate.pro < prev    next >
Text File  |  1997-07-08  |  7KB  |  196 lines

  1. ;$Id: correlate.pro,v 1.8 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1994-1997, Research Systems, Inc.  All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;+
  6. ; NAME:
  7. ;       CORRELATE
  8. ;
  9. ; PURPOSE:
  10. ;       This function computes the linear Pearson correlation coefficient
  11. ;       of two vectors or the Correlation Matrix of an M x N array. 
  12. ;       Alternatively, this function computes the covariance of two vectors 
  13. ;       or the Covariance Matrix of an M x N array.
  14. ;
  15. ; CATEGORY:
  16. ;       Statistics.
  17. ;
  18. ; CALLING SEQUENCE:
  19. ;       Result = Correlate(X [,Y])
  20. ;
  21. ; INPUTS:
  22. ;       X:    A vector or an M x N array of type integer, float or double.
  23. ;       Y:    A vector of type integer, float or double. If X is an M x N 
  24. ;             array, this parameter should not be supplied.
  25. ;
  26. ; KEYWORD PARAMETERS:
  27. ;       COVARIANCE:    If set to a non-zero value, the sample covariance is 
  28. ;                      computed. 
  29. ;
  30. ;       DOUBLE:        If set to a non-zero value, computations are done in
  31. ;                      double precision arithmetic.
  32. ;       
  33. ; RESTRICTIONS:
  34. ;       If X is an M x N array, then Y should not be supplied; 
  35. ;       Result = Correlate(X)
  36. ;
  37. ; EXAMPLES:
  38. ;       Define the data vectors.
  39. ;         x = [65, 63, 67, 64, 68, 62, 70, 66, 68, 67, 69, 71]
  40. ;         y = [68, 66, 68, 65, 69, 66, 68, 65, 71, 67, 68, 70]
  41. ;
  42. ;       Compute the linear Pearson correlation coefficient of x and y.
  43. ;         result = correlate(x, y)
  44. ;       The result should be 0.702652
  45. ;
  46. ;       Compute the covariance of x and y.
  47. ;         result = correlate(x, y, /covariance)
  48. ;       The result should be 3.66667
  49. ;  
  50. ;       Define an array with x and y as its columns.
  51. ;         a = [transpose(x), transpose(y)]
  52. ;       Compute the correlation matrix.
  53. ;         result = correlate(a)
  54. ;       The result should be [[1.000000,  0.702652]
  55. ;                             [0.702652,  1.000000]]
  56. ;
  57. ;       Compute the covariance matrix.
  58. ;         result = correlate(a, /covariance)
  59. ;       The result should be [[7.69697,  3.66667]
  60. ;                             [3.66667,  3.53788]]
  61. ;
  62. ; PROCEDURE:
  63. ;       CORRELATE computes the linear Pearson correlation coefficient of
  64. ;       two vectors. If the vectors are of unequal length, the longer vector
  65. ;       is truncated to the length of the shorter vector. If X is an M x N 
  66. ;       array, M-columns by N-rows, the result will be an M x M array of 
  67. ;       linear Pearson correlation coefficients with the iTH column and jTH 
  68. ;       row element corresponding to the correlation of the iTH and jTH 
  69. ;       columns of the M x N array. The M x M array of linear Pearson 
  70. ;       correlation coefficients (also known as the Correlation Matrix) is 
  71. ;       always symmetric and contains 1s on the main diagonal. The Covariance
  72. ;       Matrix is also symmetric, but is not restricted to 1s on the main
  73. ;       diagonal. 
  74. ;
  75. ; REFERENCE:
  76. ;       APPLIED STATISTICS (third edition)
  77. ;       J. Neter, W. Wasserman, G.A. Whitmore
  78. ;       ISBN 0-205-10328-6
  79. ;
  80. ; MODIFICATION HISTORY:
  81. ;       Written by:  DMS, RSI, Sept 1983
  82. ;       Modified:    GGS, RSI, July 1994
  83. ;                    Added COVARIANCE keyword.
  84. ;                    Included support for matrix input.  
  85. ;                    New documentation header.
  86. ;       Modified:    GGS, RSI, April 1996
  87. ;                    Included support for scalar and unequal length vector
  88. ;                    inputs. Added checking for undefined correlations and
  89. ;                    support of IEEE NaN (Not a Number). 
  90. ;                    Added DOUBLE keyword.
  91. ;                    Modified keyword checking and use of double precision.
  92. ;-
  93. FUNCTION DATOTAL, Arg, Double = Double
  94.  
  95.   Type = SIZE(Arg)
  96.   if N_ELEMENTS(Double) eq 0 then $
  97.     Double = (Type[Type[0]+1] eq 5)
  98.   ArgSum = TOTAL(Arg, Double = Double)
  99.   if Type[Type[0]+1] eq 5 and Double eq 0 then $
  100.     RETURN, FLOAT(ArgSum) else RETURN, ArgSum
  101.  
  102. END
  103.  
  104. FUNCTION Cov_Mtrx, X, Double = Double
  105.   Nx = SIZE(x)
  106.   if N_ELEMENTS(Double) eq 0 then Double = (Nx[Nx[0]+1] eq 5) 
  107.   if Double eq 0 then one = 1.0 else one = 1.0d
  108.   if nx[0] eq 0 or nx[0] eq 1 then RETURN, one $
  109.   else begin 
  110.     VarXi = X - (X # REPLICATE(one/nx[2], nx[2])) # REPLICATE(one, nx[2])
  111.     VarXi = (VarXi # TRANSPOSE(VarXi)) / (nx[2]-1)
  112.     if Double eq 0 then RETURN, FLOAT(VarXi) else RETURN, VarXi
  113.   endelse
  114. end
  115.  
  116. FUNCTION CRR_MTRX, X, Double = Double
  117.   Nx = SIZE(x)
  118.   if N_ELEMENTS(Double) eq 0 then Double = (Nx[Nx[0]+1] eq 5)
  119.   if Double eq 0 then one = 1.0 else one = 1.0d
  120.   if Nx[0] eq 0 or Nx[0] eq 1 then RETURN, one $
  121.   else begin
  122.     VarXi = x - (x # REPLICATE(one/Nx[2], Nx[2])) # REPLICATE(one, Nx[2])
  123.     SS = VarXi^2 # REPLICATE(one, Nx[2])
  124.     SS = SS # SS
  125.     if Double eq 0 then Tol = 1.0e-6 else Tol = 1.0d-12
  126.     iSS = WHERE(ABS(SS) le Tol, nSS) ;Zero denominator signals undefined
  127.                                      ;Correlation.
  128.     if nSS ne 0 then begin
  129.       SS[iSS] = one
  130.       cm = (VarXi # TRANSPOSE(VarXi))/SQRT(SS)
  131.       cm[iSS] = !VALUES.F_NAN
  132.       if Double eq 0 then RETURN, FLOAT(cm) else RETURN, cm
  133.     endif else $
  134.       if Double eq 0 then RETURN, FLOAT((VarXi # TRANSPOSE(VarXi))/SQRT(SS)) $
  135.       else RETURN, (VarXi # TRANSPOSE(VarXi))/SQRT(SS)
  136.   endelse
  137. end
  138.  
  139. FUNCTION Correlate, X, Y, Covariance = Covariance, Double = Double
  140.  
  141.   ON_ERROR, 2  ;Return to caller if an error occurs.
  142.  
  143.   if N_PARAMS() eq 2 then begin  ;Vector inputs.
  144.  
  145.     Sx = SIZE(x)  &  Sy = SIZE(y)
  146.     if N_ELEMENTS(Double) eq 0 then $
  147.       Double = (Sx[Sx[0]+1] eq 5) or (Sy[Sy[0]+1] eq 5)
  148.  
  149.     Nx = Sx[Sx[0]+2]
  150.     Ny = Sy[Sy[0]+2]
  151.  
  152.     ;If not of equal length, take shortest.
  153.     if Nx lt Ny then begin
  154.       yMem = Y[Nx:*] & Y = Y[0:Nx-1]
  155.     endif else $
  156.     if Ny lt Nx then begin
  157.       xMem = X[Ny:*] & X = X[0:Ny-1]
  158.     endif
  159.  
  160.     ;Means.
  161.     sLength = MIN([Nx, Ny])
  162.     xMean = DATOTAL(X, Double = Double) / sLength
  163.     yMean = DATOTAL(Y, Double = Double) / sLength
  164.  
  165.     ;Deviations.
  166.     xDev = X - xMean
  167.     yDev = Y - yMean
  168.  
  169.     ;If not of equal length, restore input vector.
  170.     if Nx lt Ny then Y = [Y, yMem] else $
  171.     if Ny lt Nx then X = [X, xMem] 
  172.  
  173.     if KEYWORD_SET(Covariance) eq 0 then begin  ;Correlation.
  174.       Denom = DATOTAL(xDev^2, Double = Double) * $
  175.               DATOTAL(yDev^2, Double = Double)
  176.       if Double eq 0 then Tol = 1.0e-6 else Tol = 1.0d-12
  177.       iDenom = WHERE(ABS(Denom) le Tol, nDenom) ;Zero denominator signals 
  178.                                                 ;undefined Correlation.
  179.       if nDenom ne 0 then begin
  180.         Denom[iDenom] = 1.0
  181.         cr = DATOTAL(xDev * yDev, Double = Double)/SQRT(Denom)
  182.         cr[iDenom] = !VALUES.F_NAN
  183.         RETURN, cr
  184.       endif else RETURN, DATOTAL(xDev * yDev, Double = Double)/SQRT(Denom)
  185.     endif else begin ;Covariance.
  186.       if sLength eq 1 then RETURN, !VALUES.F_NAN $
  187.       else RETURN, DATOTAL(xDev * yDev, Double = Double) / (sLength-1)
  188.     endelse
  189.   endif else begin ;Array input.         
  190.     if KEYWORD_SET(Covariance) eq 0 then RETURN, $
  191.       CRR_MTRX(X, Double = Double) $  ;Correlation Matrix.
  192.     else RETURN, COV_MTRX(X, Double = Double)  ;Covariance Matrix.
  193.   endelse
  194. END
  195.